﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DDD4Fun.Mediator
{
    public class WeakAction
    {
        private readonly Action _action;
        private WeakReference _reference;

        public Action Action
        {
            get
            {
                return this._action;
            }
        }

        public bool IsAlive
        {
            get
            {
                return this._reference != null && this._reference.IsAlive;
            }
        }

        public object Target
        {
            get
            {
                if (this._reference == null)
                {
                    return null;
                }
                return this._reference.Target;
            }
        }

        public WeakAction(object target, Action action)
        {
            this._reference = new WeakReference(target);
            this._action = action;
        }

        public void Execute()
        {
            if (this._action != null && this.IsAlive)
            {
                this._action.Invoke();
            }
        }

        public void MarkForDeletion()
        {
            this._reference = null;
        }
    }

    public class WeakAction<T> : WeakAction, IExecuteWithObject
    {
        private readonly Action<T> _action;

        public new Action<T> Action
        {
            get
            {
                return this._action;
            }
        }

        public WeakAction(object target, Action<T> action)
            : base(target, null)
        {
            this._action = action;
        }

        public void Execute()
        {
            if (this._action != null && base.IsAlive)
            {
                this._action.Invoke(default(T));
            }
        }

        public void Execute(T parameter)
        {
            if (this._action != null && base.IsAlive)
            {
                this._action.Invoke(parameter);
            }
        }

        public void ExecuteWithObject(object parameter)
        {
            T parameter2 = (T)parameter;
            this.Execute(parameter2);
        }
    }
}
